﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
//using System.Net;
//using System.IO;

namespace GW2_Marketeer
{
    public partial class GUI : Form
    {
        int m_nItemCount;
        List<string> m_listItemNames;
        Marketeer m_market;

        public GUI()
        {
            InitializeComponent();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openXMLFileDialog();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void toolStripButtonOpenFile_Click(object sender, EventArgs e)
        {
            openXMLFileDialog();
        }

        /*private void toolStripButton2_Click(object sender, EventArgs e)
        {
            Dictionary<string, int> dict = new Dictionary<string, int>();
            for(int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                try
                {
                    string sValue = labelItemValueAHPrice[i].Text;
                    int nValue = Convert.ToInt32(sValue);
                    dict[sName] = nValue;
                }
                catch
                {
                    MessageBox.Show("Error reading Auction House price of Item " + sName + ".");
                    return;
                }
            }

            m_market.ReadAHPricesFromGUI(dict);
            m_market.CalculateMinimumPrices();
            m_market.CalculateProfit();

            // Update GUI
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                labelItemValueCalcPrice[i].Text = item.MinimumCalculatedPrice.ToString();
                labelItemValueProfit[i].Text = item.Profit.ToString();
                double dROI = item.ReturnOnInvestment;
                labelItemPercentProfit[i].Text = item.ReturnOnInvestment.ToString("P1");
                if (dROI < 0.00)
                {
                    labelItemPercentProfit[i].BackColor = Color.Red;
                }
                else if (dROI < 0.05)
                {
                    labelItemPercentProfit[i].BackColor = Color.Orange;
                }
                else if (dROI < 0.10)
                {
                    labelItemPercentProfit[i].BackColor = Color.Yellow;
                }
                else if (dROI < 0.15)
                {
                    labelItemPercentProfit[i].BackColor = Color.YellowGreen;
                }
                else
                {
                    labelItemPercentProfit[i].BackColor = Color.Green;
                }
            }

        }*/

        private void DoComputeShoppingList()
        {
            Dictionary<string, int> dict = new Dictionary<string, int>();
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                try
                {
                    string sValue = labelItemNumToCraft[i].Text;
                    if (sValue == "")
                    {
                        continue;
                    }
                    int nValue = Convert.ToInt32(sValue);
                    dict[sName] = nValue;
                }
                catch
                {
                    MessageBox.Show("Error reading number of Item " + sName + " to craft.");
                    return;
                }
            }

            m_market.ReadNumToCraftFromGUI(dict);

            m_market.CalculateShoppingList();

            m_market.CalculateTotals();

            // Update GUI
            Dictionary<string, int> dictNums = m_market.GetShoppingListNumItemsToBuy();
            Dictionary<string, int> dictPriceTotals = m_market.GetShoppingListPriceTotals();
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                int nNum = dictNums[sName];
                labelItemNumToBuy[i].Text = nNum.ToString();
                int nPriceTotal = dictPriceTotals[sName];
                labelItemTotalBuyingCost[i].Text = nPriceTotal.ToString();
            }

            textTotalCost.Text = m_market.GetTotalCost().ToString();
            textTotalRevenue.Text = m_market.GetTotalRevenue().ToString();
            textProfit.Text = m_market.GetTotalProfit().ToString();
            textExpectedROI.Text = m_market.GetTotalExpectedROI().ToString("P1");
        }

        private void toolStripButtonComputeShoppingList_Click(object sender, EventArgs e)
        {
            DoComputeShoppingList();
        }

        private void openXMLFileDialog()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "xml files (*.xml)|*.xml|All file (*.*)|*.*";
            dlg.RestoreDirectory = true;
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                m_nItemCount = 0;
                m_listItemNames = new List<string>();
                m_market = new Marketeer();

                m_market.ImportXMLData(dlg.FileName);
                m_nItemCount = m_market.GetItemCount();
                m_listItemNames = m_market.GetListItemNames();

                InitializeNonDesignComponents(m_nItemCount, m_listItemNames);
            }
        }

        /*private void toolStripButton4_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                string sID = item.ID;

                GW2SpidyRequest request = new GW2SpidyRequest(sID);

                int nValue = request.GetPriceTestString();

                labelItemValueAHPrice[i].Text = nValue.ToString();
            }
        }*/

        private void toolStripButtonGetPrices_Click(object sender, EventArgs e)
        {
            DoGW2SpidyStuff();
        }

        private void toolStripButtonGetPrices2_Click(object sender, EventArgs e)
        {
            DoGuildWarsTradeStuff();
        }

        private void toolStripButtonDoCalculations_Click(object sender, EventArgs e)
        {
            DoManualStuff();
        }

        private void menuItemGuildWarsTrader_Click(object sender, EventArgs e)
        {
            DoGW2SpidyStuff();
        }

        private void menuItemGW2Spidy_Click(object sender, EventArgs e)
        {
            DoGuildWarsTradeStuff();
        }

        private void menuItemShoppingList_Click(object sender, EventArgs e)
        {
            DoComputeShoppingList();
        }

        private void DoGW2SpidyStuff()
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                string sID = item.ID;

                GW2SpidyRequest request = new GW2SpidyRequest(sID);

                int nValue = request.GetPrice();

                labelItemValueAHPrice[i].Text = nValue.ToString();
            }

            Dictionary<string, int> dict = new Dictionary<string, int>();
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                try
                {
                    string sValue = labelItemValueAHPrice[i].Text;
                    int nValue = Convert.ToInt32(sValue);
                    dict[sName] = nValue;
                }
                catch
                {
                    MessageBox.Show("Error reading Auction House price of Item " + sName + ".");
                    return;
                }
            }

            m_market.ReadAHPricesFromGUI(dict);
            m_market.CalculateMinimumPrices();
            m_market.CalculateProfit();

            // Update GUI
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                labelItemValueCalcPrice[i].Text = item.MinimumCalculatedPrice.ToString();
                labelItemValueProfit[i].Text = item.Profit.ToString();
                double dROI = item.ReturnOnInvestment;
                labelItemPercentProfit[i].Text = item.ReturnOnInvestment.ToString("P1");
                if (dROI < 0.00)
                {
                    labelItemPercentProfit[i].BackColor = Color.Red;
                }
                else if (dROI < 0.05)
                {
                    labelItemPercentProfit[i].BackColor = Color.Orange;
                }
                else if (dROI < 0.10)
                {
                    labelItemPercentProfit[i].BackColor = Color.Yellow;
                }
                else if (dROI < 0.15)
                {
                    labelItemPercentProfit[i].BackColor = Color.YellowGreen;
                }
                else
                {
                    labelItemPercentProfit[i].BackColor = Color.Green;
                }
            }
        }

        private void DoGuildWarsTradeStuff()
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                string sID = item.ID;

                GuildWarsTradeRequest request = new GuildWarsTradeRequest(sID);

                int nValue = request.GetPrice();

                labelItemValueAHPrice[i].Text = nValue.ToString();
            }

            Dictionary<string, int> dict = new Dictionary<string, int>();
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                try
                {
                    string sValue = labelItemValueAHPrice[i].Text;
                    int nValue = Convert.ToInt32(sValue);
                    dict[sName] = nValue;
                }
                catch
                {
                    MessageBox.Show("Error reading Auction House price of Item " + sName + ".");
                    return;
                }
            }

            m_market.ReadAHPricesFromGUI(dict);
            m_market.CalculateMinimumPrices();
            m_market.CalculateProfit();

            // Update GUI
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                labelItemValueCalcPrice[i].Text = item.MinimumCalculatedPrice.ToString();
                labelItemValueProfit[i].Text = item.Profit.ToString();
                double dROI = item.ReturnOnInvestment;
                labelItemPercentProfit[i].Text = item.ReturnOnInvestment.ToString("P1");
                if (dROI < 0.00)
                {
                    labelItemPercentProfit[i].BackColor = Color.Red;
                }
                else if (dROI < 0.05)
                {
                    labelItemPercentProfit[i].BackColor = Color.Orange;
                }
                else if (dROI < 0.10)
                {
                    labelItemPercentProfit[i].BackColor = Color.Yellow;
                }
                else if (dROI < 0.15)
                {
                    labelItemPercentProfit[i].BackColor = Color.YellowGreen;
                }
                else
                {
                    labelItemPercentProfit[i].BackColor = Color.Green;
                }
            }
        }

        private void DoManualStuff()
        {
            Dictionary<string, int> dict = new Dictionary<string, int>();
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                try
                {
                    string sValue = labelItemValueAHPrice[i].Text;
                    int nValue = Convert.ToInt32(sValue);
                    dict[sName] = nValue;
                }
                catch
                {
                    MessageBox.Show("Error reading Auction House price of Item " + sName + ".");
                    return;
                }
            }

            m_market.ReadAHPricesFromGUI(dict);
            m_market.CalculateMinimumPrices();
            m_market.CalculateProfit();

            // Update GUI
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_market.GetItemByName(sName);

                labelItemValueCalcPrice[i].Text = item.MinimumCalculatedPrice.ToString();
                labelItemValueProfit[i].Text = item.Profit.ToString();
                double dROI = item.ReturnOnInvestment;
                labelItemPercentProfit[i].Text = item.ReturnOnInvestment.ToString("P1");
                if (dROI < 0.00)
                {
                    labelItemPercentProfit[i].BackColor = Color.Red;
                }
                else if (dROI < 0.05)
                {
                    labelItemPercentProfit[i].BackColor = Color.Orange;
                }
                else if (dROI < 0.10)
                {
                    labelItemPercentProfit[i].BackColor = Color.Yellow;
                }
                else if (dROI < 0.15)
                {
                    labelItemPercentProfit[i].BackColor = Color.YellowGreen;
                }
                else
                {
                    labelItemPercentProfit[i].BackColor = Color.Green;
                }
            }
        }

        /*int m_nItemCount;
        List<string> m_listItemNames;
        Dictionary<string, GWItem> m_listItems;
        Dictionary<string, int> m_dictItemsToBuy;

        public GUI()
        {
            InitializeComponent();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "xml files (*.xml)|*.xml|All file (*.*)|*.*";
            dlg.RestoreDirectory = true;
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                ReadXmlFile(dlg.FileName);

                m_nItemCount = m_listItemNames.Count;

                InitializeNonDesignComponents(m_nItemCount, m_listItemNames);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private bool ReadXmlFile(string sFileName)
        {
            m_listItems = new Dictionary<string, GWItem>();
            m_dictItemsToBuy = new Dictionary<string, int>();
            m_listItemNames = new List<string>();

            
            
            XmlTextReader xml = new XmlTextReader(sFileName);
            xml.WhitespaceHandling = WhitespaceHandling.All;
            xml.Read();
            xml.Read();
            while (xml.Read())// Item Element
            {
                if (xml.Name == "why")
                {
                    break;
                }
                xml.Read(); // Whitespace
                xml.Read(); // Name Element
                xml.Read(); // Name Text
                string sName = xml.Value;
                GWItem item = new GWItem(sName);
                xml.Read(); // Name End Element
                xml.Read(); // Whitespace
                xml.Read(); // Components Element
                xml.Read(); // Either Components Text or End Element, check
                if (xml.NodeType == XmlNodeType.Text)
                {
                    string sComponentsList = xml.Value;
                    string[] asComponents = sComponentsList.Split(',');
                    foreach (string sComponent in asComponents)
                    {
                        string[] asComponentBreakdown = sComponent.Split('(');
                        asComponentBreakdown[1] = asComponentBreakdown[1].Substring(0, asComponentBreakdown[1].Length - 1);
                        int nNum = Convert.ToInt32(asComponentBreakdown[1]);
                        //item.Name = sName;
                        for (int i = 0; i < nNum; i++)
                        {
                            item.AddComponent(asComponentBreakdown[0]);
                        }
                    }
                    xml.Read(); // Components End Element
                }
                m_listItemNames.Add(sName);
                m_listItems[sName] = item;
                // Components End Element has been read at this point, so continue on
                xml.Read(); // Whitespace
                xml.Read(); // Item End Element
                xml.Read(); // Whitespace
            }

            foreach (KeyValuePair<string, GWItem> pair in m_listItems)
            {
                string sName = pair.Key;
                GWItem item = pair.Value;
                Console.WriteLine("{0}", sName);
                for (int i = 0; i < item.GetNumComponents(); i++)
                {
                    Console.WriteLine("\t{0}", item.GetComponentAtIndex(i));
                }
            }

            return true;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "xml files (*.xml)|*.xml|All file (*.*)|*.*";
            dlg.RestoreDirectory = true;
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                ReadXmlFile(dlg.FileName);

                m_nItemCount = m_listItemNames.Count;

                InitializeNonDesignComponents(m_nItemCount, m_listItemNames);
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (CaptureAHInputPrices() == false)
            {
                return;
            }

            ComputeCraftingPrice();

            DetermineProfit();
        }

        private bool CaptureAHInputPrices()
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                string sValue = labelItemValueAHPrice[i].Text;
                if (sValue == "")
                {
                    sValue = "0";
                }
                int nValue;
                try
                {
                    nValue = Convert.ToInt32(sValue);
                }
                catch
                {
                    MessageBox.Show("Error reading in Auction House price of " + m_listItemNames[i]);
                    return false;
                }
                m_listItems[sName].AuctionHousePrice = nValue;
            }

            return true;
        }

        private void ComputeCraftingPrice()
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_listItems[sName];
                ComputeCheapestPrice(item);

                labelItemValueCalcPrice[i].Text = item.MinimumCalculatedPrice.ToString();

                Console.WriteLine("Shopping List for {0}", item.Name);
                for (int j = 0; j < item.GetNumShoppingList(); j++)
                {
                    Console.WriteLine("\t{0}", item.GetShoppingListItemAtIndex(j));
                }
            }
        }

        private void ComputeCheapestPrice(GWItem item)
        {
            if(item.CheapestPriceComputed == true)
            {
                return;
            }
            if(item.GetNumComponents() == 0)
            {
                item.MinimumCalculatedPrice = item.AuctionHousePrice;
                item.AddToShoppingList(item.Name);
                item.CheapestPriceComputed = true;
                return;
            }
            else
            {
                int nTotalPrice = 0;
                for(int i = 0; i < item.GetNumComponents(); i++)
                {
                    string sComponent = item.GetComponentAtIndex(i);
                    GWItem itemComp = m_listItems[sComponent];
                    ComputeCheapestPrice(itemComp);
                    nTotalPrice += itemComp.MinimumCalculatedPrice;
                    int numShoppingListComps = itemComp.GetNumShoppingList();
                    for (int j = 0; j < itemComp.GetNumShoppingList(); j++)
                    {
                        item.AddToShoppingList(itemComp.GetShoppingListItemAtIndex(j));
                    }
                }
                if(nTotalPrice > item.AuctionHousePrice)
                {
                    nTotalPrice = item.AuctionHousePrice;
                    item.ClearShoppingList();
                    item.AddToShoppingList(item.Name);
                }
                item.MinimumCalculatedPrice = nTotalPrice;
                item.CheapestPriceComputed = true;
                return;
            }
        }

        public void DetermineProfit()
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                GWItem item = m_listItems[sName];
                int nAHPrice = item.AuctionHousePrice;
                int nMinPrice = item.MinimumCalculatedPrice;
                double dAHPrice = (double)nAHPrice;
                dAHPrice *= 0.85;
                nAHPrice = (int)dAHPrice;
                int nProfit = nAHPrice - nMinPrice;
                item.Profit = nProfit;
                labelItemValueProfit[i].Text = nProfit.ToString();
                double dPercent = (((double)nAHPrice / (double)nMinPrice) - 1.0);
                if (dPercent > 1000.0)
                {
                    labelItemPercentProfit[i].Text = dPercent.ToString("P0");
                }
                else
                {
                    labelItemPercentProfit[i].Text = dPercent.ToString("P1");
                }
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                //m_dictItemsToBuy.Add(sName, 0);
                m_dictItemsToBuy[sName] = 0;
            }

            int nTotalCost = 0, nTotalRevenue = 0;

            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                string sValue = labelItemNumToCraft[i].Text;
                int nValue;

                // Validate num to buy
                if (sValue == "")
                {
                    continue;
                }
                try
                {
                    nValue = Convert.ToInt32(sValue);
                }
                catch
                {
                    MessageBox.Show("Error reading in number of Item " + sName + " to buy.");
                    return;
                }

                // Add components in
                GWItem item = m_listItems[sName];
                for(int k = 0; k < nValue; k++)
                {
                    nTotalRevenue += item.AuctionHousePrice;
                    for (int j = 0; j < item.GetNumShoppingList(); j++)
                    {
                        string sComponent = item.GetShoppingListItemAtIndex(j);
                        m_dictItemsToBuy[sComponent] += 1;
                    }
                }
            }

            for (int i = 0; i < m_nItemCount; i++)
            {
                string sName = m_listItemNames[i];
                labelItemNumToBuy[i].Text = m_dictItemsToBuy[sName].ToString();
                GWItem item = m_listItems[sName];
                int nPrice = item.MinimumCalculatedPrice;
                int nTotalPrice = m_dictItemsToBuy[sName] * nPrice;
                nTotalCost += nTotalPrice;
                labelItemTotalBuyingCost[i].Text = nTotalPrice.ToString();
            }

            double dTotalRevenue = (double)nTotalRevenue * 0.85;
            nTotalRevenue = (int)dTotalRevenue;
            int nTotalProfit = nTotalRevenue - nTotalCost;
            double dTotalExpectedROI = ((double)nTotalRevenue / (double)nTotalCost) - 1.0;

            textTotalCost.Text = nTotalCost.ToString();
            textTotalRevenue.Text = nTotalRevenue.ToString();
            textProfit.Text = nTotalProfit.ToString();
            textExpectedROI.Text = dTotalExpectedROI.ToString("P1");
        }*/
    }
}

/*string url = "http://www.gw2spidy.com/item/19701";

            var sb = new StringBuilder();
            var buf = new byte[8192];

            try
            {
                // prepare the web page we will be asking for
                var request = (HttpWebRequest)
                                         WebRequest.Create(url);

                /* Using the proxy class to access the site
                 * Uri proxyURI = new Uri("http://proxy.com:80");
                 request.Proxy = new WebProxy(proxyURI);
                 request.Proxy.Credentials = new NetworkCredential("proxyuser", "proxypassword");*/

                // execute the request
                /*var response = (HttpWebResponse)
                                           request.GetResponse();

                // we will read data via the response stream
                Stream resStream = response.GetResponseStream();

                string tempString = null;
                int count = 0;

                do
                {
                    // fill the buffer with data
                    count = resStream.Read(buf, 0, buf.Length);

                    // make sure we read some data
                    if (count != 0)
                    {
                        // translate from bytes to ASCII text
                        tempString = Encoding.ASCII.GetString(buf, 0, count);

                        // continue building the string
                        sb.Append(tempString);
                    }
                } while (count > 0); // any more data to read?

            }
            catch (Exception exception)
            {
                MessageBox.Show(@"Failed to retrieve data from the network. Please check you internet connection: " +
                                exception);
            }

            string result = sb.ToString();*/